package com.share.example.selenium.service.amazon.buy;

import com.share.common.utils.DateUtil;
import com.share.common.utils.DelayUtil;
import com.share.config.email.EMessage;
import com.share.example.selenium.enums.BusinessEnum;
import com.share.example.selenium.enums.OperateStatusEnum;
import com.share.example.selenium.service.AbsDriver;
import com.share.example.selenium.utils.DriverUtil;
import com.share.example.selenium.utils.ElementUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;

@Data
@Slf4j
@Service
public class AmazonBuyLoginService extends AbsDriver {
    private final static String BIZ_CODE = BusinessEnum.AMAZON_BUY.code;
    private final static String LOGIN_FIX_ACCOUNT_URL = "https://www.amazon.cn/ap/signin?openid.pape.max_auth_age";
    private final static String LOGIN_FIX_PASSWORD_URL = "https://www.amazon.cn/ap/signin";
    private final static String LOGIN_SUCCESS_FORWORD_URL_PRE = "https://www.amazon.cn/?ref_=nav_ya_signin";
    private final static String RE_INPUT_IMAGE_CODE_URL_PRE = "https://www.amazon.cn/errors/validateCaptcha";
    private final static String LOGIN_PRE_SUCCESS_PERSON_CHECK_URL_PRE = "https://www.amazon.cn/ap/cvf/request";

    @Autowired
    protected WebDriver driver;

    @Value("${rootUrl.ocr}")
    private String ocrUrl;

    @Override
    public void reInitDriver(WebDriver driver) {
        this.driver = driver;
    }

    //1.打开买家---填写表单页面
    public Boolean openLoginPage() {
        DriverUtil.mouseScrollTo(driver, 300, 50);//移动鼠标
        //1.打开首页
        String url = "https://www.amazon.cn/";
        String msg1 = "正在打开首页,url=" + url;
        log.info(msg1);
        Long id = operateLogService.insertLog(BIZ_CODE, msg1, OperateStatusEnum.WILL.code, null, null, new Date(), driver.getWindowHandle());
        driver.get(url);
        DelayUtil.sleepRangSecond(1, 4);
        if (pageContains("自动程序", "换一张图")) {
            log.info("系统检测到机器人操作");
            updateLogById(OperateStatusEnum.EXCEPTION.code, "系统检测到机器人操作", null, new Date(), id, driver.getWindowHandle());

            WebElement ele_img = driver.findElement(By.xpath("/html/body/div/div[1]/div[3]/div/div/form/div[1]/div/div/div[1]/img"));
            String code = ElementUtil.getImageCode(ocrUrl,ele_img, 6, 3, "url");
            DelayUtil.sleepRangSecond(1, 3);

            if (code != null || code.length() == 6) {
                WebElement ele_code = driver.findElement(By.id("captchacharacters"));
                ElementUtil.inputValue(ele_code, code, 100, 600);
                DelayUtil.sleepRangSecond(2, 4);

                WebElement ele_continue = driver.findElement(By.xpath("/html/body/div/div[1]/div[3]/div/div/form/div[2]/div/span/span/button"));
                ele_continue.submit();
                DelayUtil.sleepRangSecond(2, 4);

                String currentUrl = driver.getCurrentUrl();
                if (currentUrl.startsWith(RE_INPUT_IMAGE_CODE_URL_PRE)) {
                    //认证失败
                    return false;
                } else {
                    //验证码输入成功---会回到https://www.amazon.cn/这里
                    log.info("继续下面的操作");
                }

            } else {
                return false;
            }
        }
        updateLogById(OperateStatusEnum.SUCCESS.code, null, null, new Date(), id, driver.getWindowHandle());

        //2.点击登录
        DriverUtil.mouseScrollTo(driver, 600, 50);//移动鼠标
        String msg2 = "即将点击首页右上角的登录按钮";
        log.info(msg2);
        Long id2 = operateLogService.insertLog(BIZ_CODE, msg2, OperateStatusEnum.WILL.code, null, null, new Date(), driver.getWindowHandle());
        WebElement element = driver.findElement(By.id("nav-link-accountList-nav-line-1"));
        element.click();
        DelayUtil.sleepRangSecond(2, 4);

        String currentUrl = driver.getCurrentUrl();
        if (currentUrl.contains(LOGIN_FIX_ACCOUNT_URL)) {
            log.info("即将点击右上角的登录按钮");
            updateLogById(OperateStatusEnum.SUCCESS.code, null, null, new Date(), id2, driver.getWindowHandle());
            return true;
        } else {
            String err_msg2 = "打开登录表单页面失败,currentUrl=" + currentUrl;
            log.info(err_msg2);
            updateLogById(OperateStatusEnum.EXCEPTION.code, err_msg2, null, new Date(), id2, driver.getWindowHandle());
            return false;
        }
    }

    //填写买家账号页面
    public Boolean fixAccountLoginform(String account) {
        String currentUrl = driver.getCurrentUrl();
        if (!currentUrl.contains(LOGIN_FIX_ACCOUNT_URL)) {
            log.info("当前不是登录表单的页面,currentUrl={}", currentUrl);
            return false;
        }

        //1.填写账号
        if (StringUtils.isEmpty(account)) {
            account = "13267158278";
        }
        log.info("即将填写账号信息,account={}", account);
        WebElement ele_account = driver.findElement(By.id("ap_email"));
        ElementUtil.inputValue(ele_account, account, 100, 600);
        DelayUtil.sleepRangSecond(1, 3);

        //2.复选框---同意条款
        WebElement ele_check_box = driver.findElement(By.id("ap_legal_agreement_check_box"));
        ele_check_box.click();
        DelayUtil.sleepRangMillis(100, 500);

        //3.点击继续
        DriverUtil.mouseScrollTo(driver, 60, 50);//移动鼠标
        WebElement ele_continue = driver.findElement(By.id("continue"));
        ele_continue.click();
        DelayUtil.sleepRangSecond(2, 4);

        String forward_currentUrl = driver.getCurrentUrl();
        if (forward_currentUrl.contains(LOGIN_FIX_PASSWORD_URL)) {
            return true;
        } else {
            log.info("登录失败,forward_currentUrl={}", forward_currentUrl);
            return false;
        }
    }

    //填写买家密码页面
    public Boolean fixPassWordLoginform(String password) {
        String currentUrl = driver.getCurrentUrl();
        if (!currentUrl.contains(LOGIN_FIX_PASSWORD_URL)) {
            log.info("当前不是登录表单的页面,currentUrl={}", currentUrl);
            return false;
        }

        //1.填写密码
        if (StringUtils.isEmpty(password)) {
            password = "1qaz@wsx";
        }
        log.info("即将填写密码信息,password={}", password);
        WebElement ele_password = driver.findElement(By.id("ap_password"));
        ElementUtil.inputValue(ele_password, password, 100, 600);

        //2.点击登录
        log.info("点击登录");
        WebElement signInSubmit = driver.findElement(By.id("signInSubmit"));
        signInSubmit.submit();

        DelayUtil.sleepRangSecond(3, 10);

        String forward_currentUrl = driver.getCurrentUrl();
        if (forward_currentUrl.contains(LOGIN_PRE_SUCCESS_PERSON_CHECK_URL_PRE)) {
            String msg1 = "点击登录后弹出短信人工校验 或者 邮件校验";
            log.info(msg1);
            //1.选择邮箱方式
            WebElement ele_email = driver.findElement(By.xpath("//*[@id=\"cvf-page-content\"]/div[1]/div/div/form/div[4]/label/span"));
            ele_email.click();
            DelayUtil.sleepSecond(1);

            //2.点击发送邮件
            String msg2 = "选择并点击发送邮件";
            log.info(msg2);
            WebElement ele_continue = driver.findElement(By.id("continue"));
            ele_continue.submit();
            Date sendDate = new Date();
            DelayUtil.sleepRangSecond(15, 30);

            //3.登录邮件系统
            String emailCode = amazonBuyLoginCode(sendDate, 3);
            log.info("读取邮件获的检验码={}", emailCode);

            //4.填写code
            WebElement ele_emailCode = driver.findElement(By.id("cvf-input-code"));
            ElementUtil.inputValue(ele_emailCode, emailCode, 100, 600);

            //5.点击继续
            WebElement ele_continue_email = driver.findElement(By.xpath("//*[@id=\"cvf-submit-otp-button\"]/span/input"));
            ele_continue_email.submit();
            DelayUtil.sleepRangSecond(15, 30);
            //*[@id="cvf-submit-otp-button"]/span/input
        }

        if (forward_currentUrl.contains(LOGIN_SUCCESS_FORWORD_URL_PRE)) {
            return true;
        } else {
            log.info("登录失败,forward_currentUrl={}", forward_currentUrl);
            return false;
        }
    }

    private boolean pageContains(String... arr) {
        if (arr == null || arr.length < 0) {
            return false;
        }

        int count = 0;
        int len = arr.length;
        String pageSource = driver.getPageSource();
        for (int i = 0; i < len; i++) {
            if (pageSource.contains(arr[i])) {
                count++;
            }
        }
        return count == len;
    }


    //读取邮件中的验证码
    public String amazonBuyLoginCode(Date sendDate, int TRY_COUNT) {
        String recode = null;
        String strDate = DateUtil.getDateTime(sendDate);
        int exeCount = 0;
        do {
            exeCount++;
            log.info("第{}次开始获取邮件列表strDate={}", exeCount, strDate);
            List<EMessage> eMessageList = emailUtil.listEmail("亚马逊验证码", "account-update@amazon", "分钟后过期", sendDate, null);
            log.info("读取到的邮件数量size={},dateStart={}", eMessageList.size(), strDate);
            if (CollectionUtils.isEmpty(eMessageList)) {
                exeCount++;
                DelayUtil.sleepSecond(15);
            } else {
                int CODE_LEN = 6;
                String CODE_PRE = "\"otp\">";

                //获取最新的邮件
                EMessage eMessage = eMessageList.get(eMessageList.size() - 1);
                String content = eMessage.getContent();
                int i = content.indexOf("verificationMsg");
                int i1 = content.indexOf(CODE_PRE, i);
                String tmpPre = content.substring(i1, i1 + CODE_PRE.length() + CODE_LEN);
                String code = tmpPre.replace(CODE_PRE, "");
                log.info("第{}次提取邮件校验码,code={},conditionDate={},codeTime={}", exeCount, code, strDate, DateUtil.getDateTime(eMessage.getSentDate()));
                if (code != null && code.length() == CODE_LEN) {
                    recode = code;
                    break;
                } else {
                    DelayUtil.sleepSecond(15);
                }
            }
        } while (exeCount < TRY_COUNT);
        return recode;
    }
}
